home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1995 November / Macworld Nov ’95.toast / Developers / Flex 2.5.2 / flex-2.5.2 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-29  |  30.2 KB  |  1,247 lines  |  [TEXT/MPS ]

  1. /* flex - tool to generate fast lexical analyzers */
  2.  
  3. /*-
  4.  * Copyright (c) 1990 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  *
  10.  * The United States Government has rights in this work pursuant
  11.  * to contract no. DE-AC03-76SF00098 between the United States
  12.  * Department of Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted provided
  15.  * that: (1) source distributions retain this entire copyright notice and
  16.  * comment, and (2) distributions including binaries display the following
  17.  * acknowledgement:  ``This product includes software developed by the
  18.  * University of California, Berkeley and its contributors'' in the
  19.  * documentation or other materials provided with the distribution and in
  20.  * all advertising materials mentioning features or use of this software.
  21.  * Neither the name of the University nor the names of its contributors may
  22.  * be used to endorse or promote products derived from this software without
  23.  * specific prior written permission.
  24.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  25.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  26.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  27.  */
  28.  
  29. #ifndef lint
  30. char copyright[] =
  31. "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
  32.  All rights reserved.\n";
  33. #endif /* not lint */
  34.  
  35. /* $Header: /home/daffy/u0/vern/flex/RCS/main.c,v 2.63 95/04/20 13:53:23 vern Exp $ */
  36.  
  37. #include "flexdef.h"
  38. #include "version.h"
  39. //#include <fcntl.h>
  40. //#include "getopt.h"
  41.  
  42. static char flex_version[] = FLEX_VERSION;
  43.  
  44.  
  45. /* declare functions that have forward references */
  46.  
  47. void flexinit PROTO((int, char**));
  48. void readin PROTO((void));
  49. void set_up_initial_allocations PROTO((void));
  50.  
  51. #ifdef NEED_ARGV_FIXUP
  52. extern void argv_fixup PROTO((int *, char ***));
  53. #endif
  54.  
  55.  
  56. /* these globals are all defined and commented in flexdef.h */
  57. int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt;
  58. int interactive, caseins, lex_compat, do_yylineno, useecs, fulltbl, usemecs;
  59. int fullspd, gen_line_dirs, performance_report, backing_up_report;
  60. int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, csize;
  61. int yymore_used, reject, real_reject, continued_action, in_rule;
  62. int yymore_really_used, reject_really_used;
  63. int datapos, dataline, linenum, out_linenum;
  64. FILE *skelfile = NULL;
  65. int skel_ind = 0;
  66. char *action_array;
  67. int action_size, defs1_offset, prolog_offset, action_offset, action_index;
  68. char *infilename = NULL, *outfilename = NULL;
  69. int did_outfilename;
  70. char *prefix, *yyclass;
  71. int do_stdinit, use_stdout;
  72. int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
  73. int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
  74. int current_mns, current_max_rules;
  75. int num_rules, num_eof_rules, default_rule, lastnfa;
  76. int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2;
  77. int *accptnum, *assoc_rule, *state_type;
  78. int *rule_type, *rule_linenum, *rule_useful;
  79. int current_state_type;
  80. int variable_trailing_context_rules;
  81. int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP];
  82. int protcomst[MSP], firstprot, lastprot,
  83. #ifdef macintosh
  84.                         *protsave;
  85. #else
  86.                         protsave[PROT_SAVE_SIZE];
  87. #endif
  88. int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1];
  89. int tecbck[CSIZE + 1];
  90. int lastsc, *scset, *scbol, *scxclu, *sceof;
  91. int current_max_scs;
  92. char **scname;
  93. int current_max_dfa_size, current_max_xpairs;
  94. int current_max_template_xpairs, current_max_dfas;
  95. int lastdfa, *nxt, *chk, *tnxt;
  96. int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz;
  97. union dfaacc_union *dfaacc;
  98. int *accsiz, *dhash, numas;
  99. int numsnpairs, jambase, jamstate;
  100. int lastccl, *cclmap, *ccllen, *cclng, cclreuse;
  101. int current_maxccls, current_max_ccl_tbl_size;
  102. Char *ccltbl;
  103. char nmstr[MAXLINE];
  104. int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
  105. int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
  106. int num_backing_up, bol_needed;
  107. FILE *backing_up_file;
  108. int end_of_buffer_state;
  109. char **input_files;
  110. int num_input_files;
  111.  
  112. /* Make sure program_name is initialized so we don't crash if writing
  113.  * out an error message before getting the program name from argv[0].
  114.  */
  115. char *program_name = "flex";
  116.  
  117. #ifndef SHORT_FILE_NAMES
  118. static char *outfile_template = "lex.%s.%s";
  119. static char *backing_name = "lex.backup";
  120. #else
  121. static char *outfile_template = "lex%s.%s";
  122. static char *backing_name = "lex.bck";
  123. #endif
  124.  
  125. #ifdef MS_DOS
  126. extern unsigned _stklen = 16384;
  127. #endif
  128.  
  129. static char outfile_path[MAXLINE];
  130. static int outfile_created = 0;
  131. static char *skelname = NULL;
  132.  
  133.  
  134. int main( argc, argv )
  135. int argc;
  136. char **argv;
  137.     {
  138.     int i;
  139.  
  140. #ifdef NEED_ARGV_FIXUP
  141.     argv_fixup( &argc, &argv );
  142. #endif
  143.  
  144.     flexinit( argc, argv );
  145.  
  146.     readin();
  147.  
  148.     ntod();
  149.  
  150.     for ( i = 1; i <= num_rules; ++i )
  151.         if ( ! rule_useful[i] && i != default_rule )
  152.             line_warning( _( "rule cannot be matched" ),
  153.                     rule_linenum[i] );
  154.  
  155.     if ( spprdflt && ! reject && rule_useful[default_rule] )
  156.         line_warning(
  157.             _( "-s option given but default rule can be matched" ),
  158.             rule_linenum[default_rule] );
  159.  
  160.     /* Generate the C state transition tables from the DFA. */
  161.     make_tables();
  162.  
  163.     /* Note, flexend does not return.  It exits with its argument
  164.      * as status.
  165.      */
  166.     flexend( 0 );
  167.  
  168.     return 0;    /* keep compilers/lint happy */
  169.     }
  170.  
  171.  
  172. /* check_options - check user-specified options */
  173.  
  174. void check_options()
  175.     {
  176.     int i;
  177.  
  178.     if ( lex_compat )
  179.         {
  180.         if ( C_plus_plus )
  181.             flexerror( _( "Can't use -+ with -l option" ) );
  182.  
  183.         if ( fulltbl || fullspd )
  184.             flexerror( _( "Can't use -f or -F with -l option" ) );
  185.  
  186.         /* Don't rely on detecting use of yymore() and REJECT,
  187.          * just assume they'll be used.
  188.          */
  189.         yymore_really_used = reject_really_used = true;
  190.  
  191.         yytext_is_array = true;
  192.         do_yylineno = true;
  193.         use_read = false;
  194.         }
  195.  
  196.     if ( do_yylineno )
  197.         /* This should really be "maintain_backup_tables = true" */
  198.         reject_really_used = true;
  199.  
  200.     if ( csize == unspecified )
  201.         {
  202.         if ( (fulltbl || fullspd) && ! useecs )
  203.             csize = DEFAULT_CSIZE;
  204.         else
  205.             csize = CSIZE;
  206.         }
  207.  
  208.     if ( interactive == unspecified )
  209.         {
  210.         if ( fulltbl || fullspd )
  211.             interactive = false;
  212.         else
  213.             interactive = true;
  214.         }
  215.  
  216.     if ( fulltbl || fullspd )
  217.         {
  218.         if ( usemecs )
  219.             flexerror(
  220.             _( "-Cf/-CF and -Cm don't make sense together" ) );
  221.  
  222.         if ( interactive )
  223.             flexerror( _( "-Cf/-CF and -I are incompatible" ) );
  224.  
  225.         if ( lex_compat )
  226.             flexerror(
  227.         _( "-Cf/-CF are incompatible with lex-compatibility mode" ) );
  228.  
  229.         if ( do_yylineno )
  230.             flexerror(
  231.             _( "-Cf/-CF and %option yylineno are incompatible" ) );
  232.  
  233.         if ( fulltbl && fullspd )
  234.             flexerror( _( "-Cf and -CF are mutually exclusive" ) );
  235.         }
  236.  
  237.     if ( C_plus_plus && fullspd )
  238.         flexerror( _( "Can't use -+ with -CF option" ) );
  239.  
  240.     if ( C_plus_plus && yytext_is_array )
  241.         {
  242.         warn( _( "%array incompatible with -+ option" ) );
  243.         yytext_is_array = false;
  244.         }
  245.  
  246.     if ( useecs )
  247.         { /* Set up doubly-linked equivalence classes. */
  248.  
  249.         /* We loop all the way up to csize, since ecgroup[csize] is
  250.          * the position used for NUL characters.
  251.          */
  252.         ecgroup[1] = NIL;
  253.  
  254.         for ( i = 2; i <= csize; ++i )
  255.             {
  256.             ecgroup[i] = i - 1;
  257.             nextecm[i - 1] = i;
  258.             }
  259.  
  260.         nextecm[csize] = NIL;
  261.         }
  262.  
  263.     else
  264.         {
  265.         /* Put everything in its own equivalence class. */
  266.         for ( i = 1; i <= csize; ++i )
  267.             {
  268.             ecgroup[i] = i;
  269.             nextecm[i] = BAD_SUBSCRIPT;    /* to catch errors */
  270.             }
  271.         }
  272.  
  273.     if ( ! use_stdout )
  274.         {
  275.         FILE *prev_stdout;
  276.  
  277.         if ( ! did_outfilename )
  278.             {
  279.             char *suffix;
  280.  
  281.             if ( C_plus_plus )
  282.                 suffix = "cc";
  283.             else
  284.                 suffix = "c";
  285.  
  286.             sprintf( outfile_path, outfile_template,
  287.                 prefix, suffix );
  288.  
  289.             outfilename = outfile_path;
  290.             }
  291.  
  292.         prev_stdout = freopen( outfilename, "w", stdout );
  293. #ifdef macintosh
  294.         fsetfileinfo(outfilename, 'MPS ', 'TEXT');    // CEH
  295. #endif
  296.  
  297.         if ( prev_stdout == NULL )
  298.             lerrsf( _( "could not create %s" ), outfilename );
  299.  
  300.         outfile_created = 1;
  301.         }
  302.  
  303.     if ( skelname && (skelfile = fopen( skelname, "r" )) == NULL )
  304.         lerrsf( _( "can't open skeleton file %s" ), skelname );
  305.  
  306.     if ( strcmp( prefix, "yy" ) )
  307.         {
  308. #define GEN_PREFIX(name) out_str3( "#define yy%s %s%s\n", name, prefix, name )
  309.         if ( C_plus_plus )
  310.             GEN_PREFIX( "FlexLexer" );
  311.         else
  312.             {
  313.             GEN_PREFIX( "_create_buffer" );
  314.             GEN_PREFIX( "_delete_buffer" );
  315.             GEN_PREFIX( "_scan_buffer" );
  316.             GEN_PREFIX( "_scan_string" );
  317.             GEN_PREFIX( "_scan_bytes" );
  318.             GEN_PREFIX( "_flex_debug" );
  319.             GEN_PREFIX( "_init_buffer" );
  320.             GEN_PREFIX( "_flush_buffer" );
  321.             GEN_PREFIX( "_load_buffer_state" );
  322.             GEN_PREFIX( "_switch_to_buffer" );
  323.             GEN_PREFIX( "in" );
  324.             GEN_PREFIX( "leng" );
  325.             GEN_PREFIX( "lex" );
  326.             GEN_PREFIX( "out" );
  327.             GEN_PREFIX( "restart" );
  328.             GEN_PREFIX( "text" );
  329.  
  330.             if ( do_yylineno )
  331.                 GEN_PREFIX( "lineno" );
  332.             }
  333.  
  334.         if ( do_yywrap )
  335.             GEN_PREFIX( "wrap" );
  336.  
  337.         outn( "" );
  338.         }
  339.  
  340.     if ( did_outfilename )
  341.         line_directive_out( stdout, 0 );
  342.  
  343.     skelout();
  344.     }
  345.  
  346.  
  347. /* flexend - terminate flex
  348.  *
  349.  * note
  350.  *    This routine does not return.
  351.  */
  352.  
  353. void flexend( exit_status )
  354. int exit_status;
  355.  
  356.     {
  357.     int tblsiz;
  358. // CEH    int unlink();
  359.  
  360.     if ( skelfile != NULL )
  361.         {
  362.         if ( ferror( skelfile ) )
  363.             lerrsf( _( "input error reading skeleton file %s" ),
  364.                 skelname );
  365.  
  366.         else if ( fclose( skelfile ) )
  367.             lerrsf( _( "error closing skeleton file %s" ),
  368.                 skelname );
  369.         }
  370.  
  371.     if ( exit_status != 0 && outfile_created )
  372.         {
  373.         outfile_created = 0;    // CEH
  374.         if ( ferror( stdout ) )
  375.             lerrsf( _( "error writing output file %s" ),
  376.                 outfilename );
  377.  
  378.         else if ( fclose( stdout ) )
  379.             lerrsf( _( "error closing output file %s" ),
  380.                 outfilename );
  381.  
  382.         else if ( unlink( outfilename ) )
  383.             lerrsf( _( "error deleting output file %s" ),
  384.                 outfilename );
  385.         }
  386.  
  387.     if ( backing_up_report && backing_up_file )
  388.         {
  389.         if ( num_backing_up == 0 )
  390.             fprintf( backing_up_file, _( "No backing up.\n" ) );
  391.         else if ( fullspd || fulltbl )
  392.             fprintf( backing_up_file,
  393.                 _( "%d backing up (non-accepting) states.\n" ),
  394.                 num_backing_up );
  395.         else
  396.             fprintf( backing_up_file,
  397.                 _( "Compressed tables always back up.\n" ) );
  398.  
  399.         if ( ferror( backing_up_file ) )
  400.             lerrsf( _( "error writing backup file %s" ),
  401.                 backing_name );
  402.  
  403.         else if ( fclose( backing_up_file ) )
  404.             lerrsf( _( "error closing backup file %s" ),
  405.                 backing_name );
  406.         }
  407.  
  408.     if ( printstats )
  409.         {
  410.         fprintf( stderr, _( "%s version %s usage statistics:\n" ),
  411.             program_name, flex_version );
  412.  
  413.         fprintf( stderr, _( "  scanner options: -" ) );
  414.  
  415.         if ( C_plus_plus )
  416.             putc( '+', stderr );
  417.         if ( backing_up_report )
  418.             putc( 'b', stderr );
  419.         if ( ddebug )
  420.             putc( 'd', stderr );
  421.         if ( caseins )
  422.             putc( 'i', stderr );
  423.         if ( lex_compat )
  424.             putc( 'l', stderr );
  425.         if ( performance_report > 0 )
  426.             putc( 'p', stderr );
  427.         if ( performance_report > 1 )
  428.             putc( 'p', stderr );
  429.         if ( spprdflt )
  430.             putc( 's', stderr );
  431.         if ( use_stdout )
  432.             putc( 't', stderr );
  433.         if ( printstats )
  434.             putc( 'v', stderr );    /* always true! */
  435.         if ( nowarn )
  436.             putc( 'w', stderr );
  437.         if ( interactive == false )
  438.             putc( 'B', stderr );
  439.         if ( interactive == true )
  440.             putc( 'I', stderr );
  441.         if ( ! gen_line_dirs )
  442.             putc( 'L', stderr );
  443.         if ( trace )
  444.             putc( 'T', stderr );
  445.  
  446.         if ( csize == unspecified )
  447.             /* We encountered an error fairly early on, so csize
  448.              * never got specified.  Define it now, to prevent
  449.              * bogus table sizes being written out below.
  450.              */
  451.             csize = 256;
  452.  
  453.         if ( csize == 128 )
  454.             putc( '7', stderr );
  455.         else
  456.             putc( '8', stderr );
  457.  
  458.         fprintf( stderr, " -C" );
  459.  
  460.         if ( long_align )
  461.             putc( 'a', stderr );
  462.         if ( fulltbl )
  463.             putc( 'f', stderr );
  464.         if ( fullspd )
  465.             putc( 'F', stderr );
  466.         if ( useecs )
  467.             putc( 'e', stderr );
  468.         if ( usemecs )
  469.             putc( 'm', stderr );
  470.         if ( use_read )
  471.             putc( 'r', stderr );
  472.  
  473.         if ( did_outfilename )
  474.             fprintf( stderr, " -o%s", outfilename );
  475.  
  476.         if ( skelname )
  477.             fprintf( stderr, " -S%s", skelname );
  478.  
  479.         if ( strcmp( prefix, "yy" ) )
  480.             fprintf( stderr, " -P%s", prefix );
  481.  
  482.         putc( '\n', stderr );
  483.  
  484.         fprintf( stderr, _( "  %d/%d NFA states\n" ),
  485.             lastnfa, current_mns );
  486.         fprintf( stderr, _( "  %d/%d DFA states (%d words)\n" ),
  487.             lastdfa, current_max_dfas, totnst );
  488.         fprintf( stderr, _( "  %d rules\n" ),
  489.         num_rules + num_eof_rules - 1 /* - 1 for def. rule */ );
  490.  
  491.         if ( num_backing_up == 0 )
  492.             fprintf( stderr, _( "  No backing up\n" ) );
  493.         else if ( fullspd || fulltbl )
  494.             fprintf( stderr,
  495.             _( "  %d backing-up (non-accepting) states\n" ),
  496.                 num_backing_up );
  497.         else
  498.             fprintf( stderr,
  499.                 _( "  Compressed tables always back-up\n" ) );
  500.  
  501.         if ( bol_needed )
  502.             fprintf( stderr,
  503.                 _( "  Beginning-of-line patterns used\n" ) );
  504.  
  505.         fprintf( stderr, _( "  %d/%d start conditions\n" ), lastsc,
  506.             current_max_scs );
  507.         fprintf( stderr,
  508.             _( "  %d epsilon states, %d double epsilon states\n" ),
  509.             numeps, eps2 );
  510.  
  511.         if ( lastccl == 0 )
  512.             fprintf( stderr, _( "  no character classes\n" ) );
  513.         else
  514.             fprintf( stderr,
  515. _( "  %d/%d character classes needed %d/%d words of storage, %d reused\n" ),
  516.                 lastccl, current_maxccls,
  517.                 cclmap[lastccl] + ccllen[lastccl],
  518.                 current_max_ccl_tbl_size, cclreuse );
  519.  
  520.         fprintf( stderr, _( "  %d state/nextstate pairs created\n" ),
  521.             numsnpairs );
  522.         fprintf( stderr, _( "  %d/%d unique/duplicate transitions\n" ),
  523.             numuniq, numdup );
  524.  
  525.         if ( fulltbl )
  526.             {
  527.             tblsiz = lastdfa * numecs;
  528.             fprintf( stderr, _( "  %d table entries\n" ), tblsiz );
  529.             }
  530.  
  531.         else
  532.             {
  533.             tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend;
  534.  
  535.             fprintf( stderr,
  536.                 _( "  %d/%d base-def entries created\n" ),
  537.                 lastdfa + numtemps, current_max_dfas );
  538.             fprintf( stderr,
  539.             _( "  %d/%d (peak %d) nxt-chk entries created\n" ),
  540.                 tblend, current_max_xpairs, peakpairs );
  541.             fprintf( stderr,
  542.         _( "  %d/%d (peak %d) template nxt-chk entries created\n" ),
  543.                 numtemps * nummecs,
  544.                 current_max_template_xpairs,
  545.                 numtemps * numecs );
  546.             fprintf( stderr, _( "  %d empty table entries\n" ),
  547.                 nummt );
  548.             fprintf( stderr, _( "  %d protos created\n" ),
  549.                 numprots );
  550.             fprintf( stderr,
  551.                 _( "  %d templates created, %d uses\n" ),
  552.                 numtemps, tmpuses );
  553.             }
  554.  
  555.         if ( useecs )
  556.             {
  557.             tblsiz = tblsiz + csize;
  558.             fprintf( stderr,
  559.                 _( "  %d/%d equivalence classes created\n" ),
  560.                 numecs, csize );
  561.             }
  562.  
  563.         if ( usemecs )
  564.             {
  565.             tblsiz = tblsiz + numecs;
  566.             fprintf( stderr,
  567.             _( "  %d/%d meta-equivalence classes created\n" ),
  568.                 nummecs, csize );
  569.             }
  570.  
  571.         fprintf( stderr,
  572.         _( "  %d (%d saved) hash collisions, %d DFAs equal\n" ),
  573.             hshcol, hshsave, dfaeql );
  574.         fprintf( stderr, _( "  %d sets of reallocations needed\n" ),
  575.             num_reallocs );
  576.         fprintf( stderr, _( "  %d total table entries needed\n" ),
  577.             tblsiz );
  578.         }
  579.  
  580.     exit( exit_status );
  581.     }
  582.  
  583.  
  584. /* flexinit - initialize flex */
  585.  
  586. void flexinit( argc, argv )
  587. int argc;
  588. char **argv;
  589.     {
  590.     int i, sawcmpflag;
  591.     char *arg, *mktemp();
  592.  
  593.     printstats = syntaxerror = trace = spprdflt = caseins = false;
  594.     lex_compat = C_plus_plus = backing_up_report = ddebug = fulltbl = false;
  595.     fullspd = long_align = nowarn = yymore_used = continued_action = false;
  596.     do_yylineno = yytext_is_array = in_rule = reject = do_stdinit = false;
  597.     yymore_really_used = reject_really_used = unspecified;
  598.     interactive = csize = unspecified;
  599.     do_yywrap = gen_line_dirs = usemecs = useecs = true;
  600.     performance_report = 0;
  601.     did_outfilename = 0;
  602.     prefix = "yy";
  603.     yyclass = 0;
  604.     use_read = use_stdout = false;
  605.  
  606.     sawcmpflag = false;
  607.  
  608. #ifdef macintosh
  609.     protsave = (int*) allocate_array(PROT_SAVE_SIZE, sizeof(int));
  610. #endif
  611.  
  612.     /* Initialize dynamic array for holding the rule actions. */
  613.     action_size = 2048;    /* default size of action array in bytes */
  614.     action_array = allocate_character_array( action_size );
  615.     defs1_offset = prolog_offset = action_offset = action_index = 0;
  616.     action_array[0] = '\0';
  617.  
  618.     program_name = argv[0];
  619.  
  620.     if ( program_name[0] != '\0' &&
  621.          program_name[strlen( program_name ) - 1] == '+' )
  622.         C_plus_plus = true;
  623.  
  624. #if 0
  625.     do {
  626.         c = getopt(argc, argv, "bcdfhilnpstvwBFILTV78+?C::o:P:S:");
  627. /*
  628.         int option_index = 0;
  629.         static struct option long_options[] = {
  630.             {"help",    no_argument, 0, 0},
  631.             {"version", no_argument, 0, 0}
  632.         };
  633.         c = getopt_long(argc, argv, "bcdfhilnpstvwBFILTV78+?C::o:P:S:",
  634.                          long_options, &option_index);
  635. */
  636.         switch (c) {
  637.         case '+':        C_plus_plus = true;                break;
  638.         case 'B':        interactive = false;            break;
  639.         case 'b':        backing_up_report = true;        break;
  640.         case 'c':                                        break;
  641.         case 'C':
  642.             if (!sawcmpflag) {
  643.                 useecs = false;
  644.                 usemecs = false;
  645.                 fulltbl = false;
  646.                 sawcmpflag = true;
  647.             }
  648.  
  649.             while (optarg && *optarg)
  650.                 switch (*optarg++) {
  651.                     case 'a':    long_align = true;            break;
  652.                     case 'e':    useecs = true;                break;
  653.                     case 'F':    fullspd = true;                break;
  654.                     case 'f':    fulltbl = true;                break;
  655.                     case 'm':    usemecs = true;                break;
  656.                     case 'r':    use_read = true;            break;
  657.                     default:
  658.                         lerrif("unknown -C option '%c'", optarg[-1]);
  659.                         break;
  660.                 }
  661.             break;
  662.         case 'd':        ddebug = true;                    break;
  663.         case 'f':        useecs = usemecs = false;
  664.                         use_read = fulltbl = true;        break;
  665.         case 'F':        useecs = usemecs = false;
  666.                         use_read = fullspd = true;        break;
  667.         case '?':
  668.         case 'h':        usage();
  669.                         exit(0);
  670.         case 'I':        interactive = true;                break;
  671.         case 'i':        caseins = true;                    break;
  672.         case 'l':        lex_compat = true;                break;
  673.         case 'L':        gen_line_dirs = false;            break;
  674.         case 'n':                                        break;    // Stupid do-nothing deprecated option.
  675.         case 'o':        outfilename = optarg;
  676.                         did_outfilename = 1;            break;
  677.         case 'P':        prefix = optarg;                break;
  678.         case 'p':        ++performance_report;            break;
  679.         case 'S':        skelname = optarg;                break;
  680.         case 's':        spprdflt = true;                break;
  681.         case 't':        use_stdout = true;                break;
  682.         case 'T':        trace = true;                    break;
  683.         case 'v':        printstats = true;                break;
  684.         case 'V':        printf("%s version %s\n", program_name, flex_version);
  685.                         exit(0);
  686.         case 'w':        nowarn = true;                    break;
  687.         case '7':        csize = 128;                    break;
  688.         case '8':        csize = CSIZE;                    break;
  689.         case kBadOpt:
  690.         default:
  691.             fprintf(stderr, "%s: unknown flag '%c'.  For usage, try\n\t%s --help\n",
  692.                     program_name, c, program_name);
  693.             exit(1);
  694.         }
  695.     } while (c != EOF);
  696. #else
  697.  
  698.     /* read flags */
  699.     for ( --argc, ++argv; argc ; --argc, ++argv )
  700.         {
  701.         arg = argv[0];
  702.  
  703.         if ( arg[0] != '-' || arg[1] == '\0' )
  704.             break;
  705.  
  706.         if ( arg[1] == '-' )
  707.             { /* --option */
  708.             if ( ! strcmp( arg, "--help" ) )
  709.                 arg = "-h";
  710.  
  711.             else if ( ! strcmp( arg, "--version" ) )
  712.                 arg = "-V";
  713.  
  714.             else if ( ! strcmp( arg, "--" ) )
  715.                 { /* end of options */
  716.                 --argc;
  717.                 ++argv;
  718.                 break;
  719.                 }
  720.             }
  721.  
  722.         for ( i = 1; arg[i] != '\0'; ++i )
  723.             switch ( arg[i] )
  724.                 {
  725.                 case '+':
  726.                     C_plus_plus = true;
  727.                     break;
  728.  
  729.                 case 'B':
  730.                     interactive = false;
  731.                     break;
  732.  
  733.                 case 'b':
  734.                     backing_up_report = true;
  735.                     break;
  736.  
  737.                 case 'c':
  738.                     break;
  739.  
  740.                 case 'C':
  741.                     if ( i != 1 )
  742.                         flexerror(
  743.                 _( "-C flag must be given separately" ) );
  744.  
  745.                     if ( ! sawcmpflag )
  746.                         {
  747.                         useecs = false;
  748.                         usemecs = false;
  749.                         fulltbl = false;
  750.                         sawcmpflag = true;
  751.                         }
  752.  
  753.                     for ( ++i; arg[i] != '\0'; ++i )
  754.                         switch ( arg[i] )
  755.                             {
  756.                             case 'a':
  757.                                 long_align =
  758.                                     true;
  759.                                 break;
  760.  
  761.                             case 'e':
  762.                                 useecs = true;
  763.                                 break;
  764.  
  765.                             case 'F':
  766.                                 fullspd = true;
  767.                                 break;
  768.  
  769.                             case 'f':
  770.                                 fulltbl = true;
  771.                                 break;
  772.  
  773.                             case 'm':
  774.                                 usemecs = true;
  775.                                 break;
  776.  
  777.                             case 'r':
  778.                                 use_read = true;
  779.                                 break;
  780.  
  781.                             default:
  782.                                 lerrif(
  783.                         _( "unknown -C option '%c'" ),
  784.                                 (int) arg[i] );
  785.                                 break;
  786.                             }
  787.  
  788.                     goto get_next_arg;
  789.  
  790.                 case 'd':
  791.                     ddebug = true;
  792.                     break;
  793.  
  794.                 case 'f':
  795.                     useecs = usemecs = false;
  796.                     use_read = fulltbl = true;
  797.                     break;
  798.  
  799.                 case 'F':
  800.                     useecs = usemecs = false;
  801.                     use_read = fullspd = true;
  802.                     break;
  803.  
  804.                 case '?':
  805.                 case 'h':
  806.                     usage();
  807.                     exit( 0 );
  808.  
  809.                 case 'I':
  810.                     interactive = true;
  811.                     break;
  812.  
  813.                 case 'i':
  814.                     caseins = true;
  815.                     break;
  816.  
  817.                 case 'l':
  818.                     lex_compat = true;
  819.                     break;
  820.  
  821.                 case 'L':
  822.                     gen_line_dirs = false;
  823.                     break;
  824.  
  825.                 case 'n':
  826.                     /* Stupid do-nothing deprecated
  827.                      * option.
  828.                      */
  829.                     break;
  830.  
  831.                 case 'o':
  832.                     if ( i != 1 )
  833.                         flexerror(
  834.                 _( "-o flag must be given separately" ) );
  835.  
  836.                     outfilename = arg + i + 1;
  837.                     did_outfilename = 1;
  838.                     goto get_next_arg;
  839.  
  840.                 case 'P':
  841.                     if ( i != 1 )
  842.                         flexerror(
  843.                 _( "-P flag must be given separately" ) );
  844.  
  845.                     prefix = arg + i + 1;
  846.                     goto get_next_arg;
  847.  
  848.                 case 'p':
  849.                     ++performance_report;
  850.                     break;
  851.  
  852.                 case 'S':
  853.                     if ( i != 1 )
  854.                         flexerror(
  855.                 _( "-S flag must be given separately" ) );
  856.  
  857.                     skelname = arg + i + 1;
  858.                     goto get_next_arg;
  859.  
  860.                 case 's':
  861.                     spprdflt = true;
  862.                     break;
  863.  
  864.                 case 't':
  865.                     use_stdout = true;
  866.                     break;
  867.  
  868.                 case 'T':
  869.                     trace = true;
  870.                     break;
  871.  
  872.                 case 'v':
  873.                     printstats = true;
  874.                     break;
  875.  
  876.                 case 'V':
  877.                     printf( _( "%s version %s\n" ),
  878.                         program_name, flex_version );
  879.                     exit( 0 );
  880.  
  881.                 case 'w':
  882.                     nowarn = true;
  883.                     break;
  884.  
  885.                 case '7':
  886.                     csize = 128;
  887.                     break;
  888.  
  889.                 case '8':
  890.                     csize = CSIZE;
  891.                     break;
  892.  
  893.                 default:
  894.                     fprintf( stderr,
  895.         _( "%s: unknown flag '%c'.  For usage, try\n\t%s --help\n" ),
  896.                         program_name, (int) arg[i],
  897.                         program_name );
  898.                     exit( 1 );
  899.                 }
  900.  
  901.         /* Used by -C, -S, -o, and -P flags in lieu of a "continue 2"
  902.          * control.
  903.          */
  904.         get_next_arg: ;
  905.         }
  906. #endif
  907.  
  908.     num_input_files = argc;
  909.     input_files = argv;
  910.     set_input_file( num_input_files > 0 ? input_files[0] : NULL );
  911.  
  912.     lastccl = lastsc = lastdfa = lastnfa = 0;
  913.     num_rules = num_eof_rules = default_rule = 0;
  914.     numas = numsnpairs = tmpuses = 0;
  915.     numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0;
  916.     numuniq = numdup = hshsave = eofseen = datapos = dataline = 0;
  917.     num_backing_up = onesp = numprots = 0;
  918.     variable_trailing_context_rules = bol_needed = false;
  919.  
  920.     out_linenum = linenum = sectnum = 1;
  921.     firstprot = NIL;
  922.  
  923.     /* Used in mkprot() so that the first proto goes in slot 1
  924.      * of the proto queue.
  925.      */
  926.     lastprot = 1;
  927.  
  928.     set_up_initial_allocations();
  929.     }
  930.  
  931.  
  932. /* readin - read in the rules section of the input file(s) */
  933.  
  934. void readin()
  935.     {
  936.     static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;";
  937.     static char yy_nostdinit[] =
  938.         "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;";
  939.  
  940.     line_directive_out( (FILE *) 0, 1 );
  941.  
  942.     if ( yyparse() )
  943.         {
  944.         pinpoint_message( _( "fatal parse error" ) );
  945.         flexend( 1 );
  946.         }
  947.  
  948.     if ( syntaxerror )
  949.         flexend( 1 );
  950.  
  951.     if ( backing_up_report )
  952.         {
  953.         backing_up_file = fopen( backing_name, "w" );
  954.         if ( backing_up_file == NULL )
  955.             lerrsf(
  956.             _( "could not create backing-up info file %s" ),
  957.                 backing_name );
  958.         }
  959.  
  960.     else
  961.         backing_up_file = NULL;
  962.  
  963.     if ( yymore_really_used == true )
  964.         yymore_used = true;
  965.     else if ( yymore_really_used == false )
  966.         yymore_used = false;
  967.  
  968.     if ( reject_really_used == true )
  969.         reject = true;
  970.     else if ( reject_really_used == false )
  971.         reject = false;
  972.  
  973.     if ( performance_report > 0 )
  974.         {
  975.         if ( lex_compat )
  976.             {
  977.             fprintf( stderr,
  978. _( "-l AT&T lex compatibility option entails a large performance penalty\n" ) );
  979.             fprintf( stderr,
  980. _( " and may be the actual source of other reported performance penalties\n" ) );
  981.             }
  982.  
  983.         else if ( do_yylineno )
  984.             {
  985.             fprintf( stderr,
  986.     _( "%%option yylineno entails a large performance penalty\n" ) );
  987.             }
  988.  
  989.         if ( performance_report > 1 )
  990.             {
  991.             if ( interactive )
  992.                 fprintf( stderr,
  993.     _( "-I (interactive) entails a minor performance penalty\n" ) );
  994.  
  995.             if ( yymore_used )
  996.                 fprintf( stderr,
  997.         _( "yymore() entails a minor performance penalty\n" ) );
  998.             }
  999.  
  1000.         if ( reject )
  1001.             fprintf( stderr,
  1002.             _( "REJECT entails a large performance penalty\n" ) );
  1003.  
  1004.         if ( variable_trailing_context_rules )
  1005.             fprintf( stderr,
  1006. _( "Variable trailing context rules entail a large performance penalty\n" ) );
  1007.         }
  1008.  
  1009.     if ( reject )
  1010.         real_reject = true;
  1011.  
  1012.     if ( variable_trailing_context_rules )
  1013.         reject = true;
  1014.  
  1015.     if ( (fulltbl || fullspd) && reject )
  1016.         {
  1017.         if ( real_reject )
  1018.             flexerror(
  1019.                 _( "REJECT cannot be used with -f or -F" ) );
  1020.         else if ( do_yylineno )
  1021.             flexerror(
  1022.             _( "%option yylineno cannot be used with -f or -F" ) );
  1023.         else
  1024.             flexerror(
  1025.     _( "variable trailing context rules cannot be used with -f or -F" ) );
  1026.         }
  1027.  
  1028.     if ( reject )
  1029.         outn( "\n#define YY_USES_REJECT" );
  1030.  
  1031.     if ( ! do_yywrap )
  1032.         {
  1033.         outn( "\n#define yywrap() 1" );
  1034.         outn( "#define YY_SKIP_YYWRAP" );
  1035.         }
  1036.  
  1037.     if ( ddebug )
  1038.         outn( "\n#define FLEX_DEBUG" );
  1039.  
  1040.     if ( csize == 256 )
  1041.         outn( "typedef unsigned char YY_CHAR;" );
  1042.     else
  1043.         outn( "typedef char YY_CHAR;" );
  1044.  
  1045.     if ( C_plus_plus )
  1046.         {
  1047.         outn( "#define yytext_ptr yytext" );
  1048.  
  1049.         if ( interactive )
  1050.             outn( "#define YY_INTERACTIVE" );
  1051.         }
  1052.  
  1053.     else
  1054.         {
  1055.         if ( do_stdinit )
  1056.             {
  1057.             outn( "#ifdef VMS" );
  1058.             outn( "#ifndef __VMS_POSIX" );
  1059.             outn( yy_nostdinit );
  1060.             outn( "#else" );
  1061.             outn( yy_stdinit );
  1062.             outn( "#endif" );
  1063.             outn( "#else" );
  1064.             outn( yy_stdinit );
  1065.             outn( "#endif" );
  1066.             }
  1067.  
  1068.         else
  1069.             outn( yy_nostdinit );
  1070.         }
  1071.  
  1072.     if ( fullspd )
  1073.         outn( "typedef yyconst struct yy_trans_info *yy_state_type;" );
  1074.     else if ( ! C_plus_plus )
  1075.         outn( "typedef int yy_state_type;" );
  1076.  
  1077.     if ( ddebug )
  1078.         outn( "\n#define FLEX_DEBUG" );
  1079.  
  1080.     if ( lex_compat )
  1081.         outn( "#define YY_FLEX_LEX_COMPAT" );
  1082.  
  1083.     if ( do_yylineno && ! C_plus_plus )
  1084.         {
  1085.         outn( "extern int yylineno;" );
  1086.         outn( "int yylineno = 1;" );
  1087.         }
  1088.  
  1089.     if ( C_plus_plus )
  1090.         {
  1091.         outn( "\n#include <FlexLexer.h>" );
  1092.  
  1093.         if ( yyclass )
  1094.             {
  1095.             outn( "int yyFlexLexer::yylex()" );
  1096.             outn( "\t{" );
  1097.             outn(
  1098. "\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );" );
  1099.             outn( "\treturn 0;" );
  1100.             outn( "\t}" );
  1101.     
  1102.             out_str( "\n#define YY_DECL int %s::yylex()\n",
  1103.                 yyclass );
  1104.             }
  1105.         }
  1106.  
  1107.     else
  1108.         {
  1109.         if ( yytext_is_array )
  1110.             outn( "extern char yytext[];\n" );
  1111.  
  1112.         else
  1113.             {
  1114.             outn( "extern char *yytext;" );
  1115.             outn( "#define yytext_ptr yytext" );
  1116.             }
  1117.  
  1118.         if ( yyclass )
  1119.             flexerror(
  1120.         _( "%option yyclass only meaningful for C++ scanners" ) );
  1121.         }
  1122.  
  1123.     if ( useecs )
  1124.         numecs = cre8ecs( nextecm, ecgroup, csize );
  1125.     else
  1126.         numecs = csize;
  1127.  
  1128.     /* Now map the equivalence class for NUL to its expected place. */
  1129.     ecgroup[0] = ecgroup[csize];
  1130.     NUL_ec = ABS( ecgroup[0] );
  1131.  
  1132.     if ( useecs )
  1133.         ccl2ecl();
  1134.     }
  1135.  
  1136.  
  1137. /* set_up_initial_allocations - allocate memory for internal tables */
  1138.  
  1139. void set_up_initial_allocations()
  1140.     {
  1141.     current_mns = INITIAL_MNS;
  1142.     firstst = allocate_integer_array( current_mns );
  1143.     lastst = allocate_integer_array( current_mns );
  1144.     finalst = allocate_integer_array( current_mns );
  1145.     transchar = allocate_integer_array( current_mns );
  1146.     trans1 = allocate_integer_array( current_mns );
  1147.     trans2 = allocate_integer_array( current_mns );
  1148.     accptnum = allocate_integer_array( current_mns );
  1149.     assoc_rule = allocate_integer_array( current_mns );
  1150.     state_type = allocate_integer_array( current_mns );
  1151.  
  1152.     current_max_rules = INITIAL_MAX_RULES;
  1153.     rule_type = allocate_integer_array( current_max_rules );
  1154.     rule_linenum = allocate_integer_array( current_max_rules );
  1155.     rule_useful = allocate_integer_array( current_max_rules );
  1156.  
  1157.     current_max_scs = INITIAL_MAX_SCS;
  1158.     scset = allocate_integer_array( current_max_scs );
  1159.     scbol = allocate_integer_array( current_max_scs );
  1160.     scxclu = allocate_integer_array( current_max_scs );
  1161.     sceof = allocate_integer_array( current_max_scs );
  1162.     scname = allocate_char_ptr_array( current_max_scs );
  1163.  
  1164.     current_maxccls = INITIAL_MAX_CCLS;
  1165.     cclmap = allocate_integer_array( current_maxccls );
  1166.     ccllen = allocate_integer_array( current_maxccls );
  1167.     cclng = allocate_integer_array( current_maxccls );
  1168.  
  1169.     current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE;
  1170.     ccltbl = allocate_Character_array( current_max_ccl_tbl_size );
  1171.  
  1172.     current_max_dfa_size = INITIAL_MAX_DFA_SIZE;
  1173.  
  1174.     current_max_xpairs = INITIAL_MAX_XPAIRS;
  1175.     nxt = allocate_integer_array( current_max_xpairs );
  1176.     chk = allocate_integer_array( current_max_xpairs );
  1177.  
  1178.     current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS;
  1179.     tnxt = allocate_integer_array( current_max_template_xpairs );
  1180.  
  1181.     current_max_dfas = INITIAL_MAX_DFAS;
  1182.     base = allocate_integer_array( current_max_dfas );
  1183.     def = allocate_integer_array( current_max_dfas );
  1184.     dfasiz = allocate_integer_array( current_max_dfas );
  1185.     accsiz = allocate_integer_array( current_max_dfas );
  1186.     dhash = allocate_integer_array( current_max_dfas );
  1187.     dss = allocate_int_ptr_array( current_max_dfas );
  1188.     dfaacc = allocate_dfaacc_union( current_max_dfas );
  1189.  
  1190.     nultrans = (int *) 0;
  1191.     }
  1192.  
  1193.  
  1194. void
  1195. usage (void)
  1196. {
  1197.     FILE* f = stdout;
  1198.  
  1199.     fprintf(f, "%s [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix -Sskeleton]\n",
  1200.         program_name);
  1201.     fprintf(f, "\t[--help --version] [file ...]\n");
  1202.  
  1203.     fprintf(f, "\t-b  generate backing-up information to %s\n", backing_name);
  1204.     fprintf(f, "\t-c  do-nothing POSIX option\n");
  1205.     fprintf(f, "\t-d  turn on debug mode in generated scanner\n");
  1206.     fprintf(f, "\t-f  generate fast, large scanner\n");
  1207.     fprintf(f, "\t-h  produce this help message\n");
  1208.     fprintf(f, "\t-i  generate case-insensitive scanner\n");
  1209.     fprintf(f, "\t-l  maximal compatibility with original lex\n");
  1210.     fprintf(f, "\t-n  do-nothing POSIX option\n");
  1211.     fprintf(f, "\t-p  generate performance report to stderr\n");
  1212.     fprintf(f, "\t-s  suppress default rule to ECHO unmatched text\n");
  1213.  
  1214.     if (!did_outfilename) {
  1215.         sprintf(outfile_path, outfile_template, prefix, C_plus_plus ? "cc" : "c" );
  1216.         outfilename = outfile_path;
  1217.     }
  1218.  
  1219.     fprintf(f, "\t-t  write generated scanner on stdout instead of %s\n",
  1220.         outfilename);
  1221.  
  1222.     fprintf(f, "\t-v  write summary of scanner statistics to f\n");
  1223.     fprintf(f, "\t-w  do not generate warnings\n");
  1224.     fprintf(f, "\t-B  generate batch scanner (opposite of -I)\n");
  1225.     fprintf(f, "\t-F  use alternative fast scanner representation\n");
  1226.     fprintf(f, "\t-I  generate interactive scanner (opposite of -B)\n");
  1227.     fprintf(f, "\t-L  suppress #line directives in scanner\n");
  1228.     fprintf(f, "\t-T  %s should run in trace mode\n", program_name );
  1229.     fprintf(f, "\t-V  report %s version\n", program_name );
  1230.     fprintf(f, "\t-7  generate 7-bit scanner\n");
  1231.     fprintf(f, "\t-8  generate 8-bit scanner\n");
  1232.     fprintf(f, "\t-+  generate C++ scanner class\n");
  1233.     fprintf(f, "\t-?  produce this help message\n");
  1234.     fprintf(f, "\t-C  specify degree of table compression (default is -Cem):\n");
  1235.     fprintf(f, "\t\t-Ca  trade off larger tables for better memory alignment\n");
  1236.     fprintf(f, "\t\t-Ce  construct equivalence classes\n");
  1237.     fprintf(f, "\t\t-Cf  do not compress scanner tables; use -f representation\n");
  1238.     fprintf(f, "\t\t-CF  do not compress scanner tables; use -F representation\n");
  1239.     fprintf(f, "\t\t-Cm  construct meta-equivalence classes\n");
  1240.     fprintf(f, "\t\t-Cr  use read() instead of stdio for scanner input\n");
  1241.     fprintf(f, "\t-o  specify output filename\n");
  1242.     fprintf(f, "\t-P  specify scanner prefix other than \"yy\"\n");
  1243.     fprintf(f, "\t-S  specify skeleton file\n");
  1244.     fprintf(f, "\t--help     produce this help message\n");
  1245.     fprintf(f, "\t--version  report %s version\n", program_name );
  1246. }
  1247.